/*
 * Copyright (c) [2016] [ <ether.camp> ]
 * This file is part of the ethereumJ library.
 *
 * The ethereumJ library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The ethereumJ library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
 */
package org.ethereum.core;

import org.ethereum.config.SystemProperties;
import org.ethereum.core.genesis.GenesisLoader;
import org.ethereum.trie.SecureTrie;
import org.ethereum.trie.Trie;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.junit.*;
import org.junit.runners.MethodSorters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.util.Collection;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BlockTest {

    private static final Logger logger = LoggerFactory.getLogger("test");


    // https://github.com/ethereum/tests/blob/71d80bd63aaf7cee523b6ca9d12a131698d41e98/BasicTests/genesishashestest.json
    private String GENESIS_RLP = "f901f8f901f3a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a09178d0f23c965d81f0834a4c72c6253ce6830f4022b1359aaebfc1ecba442d4ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808080a0000000000000000000000000000000000000000000000000000000000000000088000000000000002ac0c0";
    private String GENESIS_HASH = "fd4af92a79c7fc2fd8bf0d342f2e832e1d4f485c85b9152d2039e03bc604fdca";
    private String GENESIS_STATE_ROOT = "9178d0f23c965d81f0834a4c72c6253ce6830f4022b1359aaebfc1ecba442d4e";

    private String MESSY_NONCE_GENESIS_RLP = "f901f8f901f3a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0da3d5bd4c2f8443fbca1f12c0b9eaa4996825e9d32d239ffb302b8f98f202c97a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008301000080832fefd8808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0";
    private String MESSY_NONCE_GENESIS_HASH = "b096cfdeb2a3c0abd3ce9f77cf5adc92a8cead34aa4d2be54c004373e3986788";

    static String TEST_GENESIS =
            "{" +
            "'0000000000000000000000000000000000000001': { 'wei': '1' }" +
            "'0000000000000000000000000000000000000002': { 'wei': '1' }" +
            "'0000000000000000000000000000000000000003': { 'wei': '1' }" +
            "'0000000000000000000000000000000000000004': { 'wei': '1' }" +
            "'dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "'e6716f9544a56c530d868e4bfbacb172315bdead': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "'b9c015918bdaba24b4ff057a92a3873d6eb201be': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "'1a26338f0d905e295fccb71fa9ea849ffa12aaf4': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "'2ef47100e0787b915105fd5e3f4ff6752079d5cb': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "'cd2a3d9f938e13cd947ec05abc7fe734df8dd826': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "'6c386a4b26f73c802f34673f7248bb118f97424a': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "'e4157b34ea9615cfbde6b4fda419828124b70c78': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
            "}";

    static {
        TEST_GENESIS = TEST_GENESIS.replace("'", "\"");
    }



    @Test
    public void testGenesisFromRLP() {
        // from RLP encoding
        byte[] genesisBytes = Hex.decode(GENESIS_RLP);
        Block genesisFromRLP = new Block(genesisBytes);
        Block genesis = GenesisLoader.loadGenesis(getClass().getResourceAsStream("/genesis/olympic.json"));
        assertEquals(Hex.toHexString(genesis.getHash()),   Hex.toHexString(genesisFromRLP.getHash()));
        assertEquals(Hex.toHexString(genesis.getParentHash()), Hex.toHexString(genesisFromRLP.getParentHash()));
        assertEquals(Hex.toHexString(genesis.getStateRoot()), Hex.toHexString(genesisFromRLP.getStateRoot()));
    }

    private Block loadGenesisFromFile(String resPath) {
        Block genesis = GenesisLoader.loadGenesis(getClass().getResourceAsStream(resPath));
        logger.info(genesis.toString());

        logger.info("genesis hash: [{}]", Hex.toHexString(genesis.getHash()));
        logger.info("genesis rlp: [{}]", Hex.toHexString(genesis.getEncoded()));

        return genesis;
    }

    @Test
    public void testGenesisFromNew() {
        Block genesis = loadGenesisFromFile("/genesis/olympic.json");

        assertEquals(GENESIS_HASH, Hex.toHexString(genesis.getHash()));
        assertEquals(GENESIS_RLP, Hex.toHexString(genesis.getEncoded()));
    }

    /**
     * Test genesis loading from JSON with some
     * freedom for user like odd length of hex values etc.
     */
    @Test
    public void testGenesisFromNewMessy() {
        Block genesis = loadGenesisFromFile("/genesis/olympic-messy.json");

        assertEquals(GENESIS_HASH, Hex.toHexString(genesis.getHash()));
        assertEquals(GENESIS_RLP, Hex.toHexString(genesis.getEncoded()));
    }

    /**
     * Test genesis with empty nonce
     * + alloc addresses with 0x
     */
    @Test
    public void testGenesisEmptyNonce() {
        Block genesis = loadGenesisFromFile("/genesis/nonce-messy.json");

        assertEquals(MESSY_NONCE_GENESIS_HASH, Hex.toHexString(genesis.getHash()));
        assertEquals(MESSY_NONCE_GENESIS_RLP, Hex.toHexString(genesis.getEncoded()));
    }

    /**
     * Test genesis with short nonce
     * + alloc addresses with 0x
     */
    @Test
    public void testGenesisShortNonce() {
        Block genesis = loadGenesisFromFile("/genesis/nonce-messy2.json");

        assertEquals(MESSY_NONCE_GENESIS_HASH, Hex.toHexString(genesis.getHash()));
        assertEquals(MESSY_NONCE_GENESIS_RLP, Hex.toHexString(genesis.getEncoded()));
    }

    @Test
    public void testGenesisPremineData() {
        Genesis genesis = GenesisLoader.loadGenesis(getClass().getResourceAsStream("/genesis/olympic.json"));
        Collection<Genesis.PremineAccount> accounts = genesis.getPremine().values();
        assertTrue(accounts.size() == 12);
    }


    @Test
    public void testPremineFromJSON() throws ParseException {

        JSONParser parser = new JSONParser();
        JSONObject genesisMap = (JSONObject) parser.parse(TEST_GENESIS);

        Set keys = genesisMap.keySet();

        Trie state = new SecureTrie((byte[]) null);

        for (Object key : keys) {

            JSONObject val = (JSONObject) genesisMap.get(key);
            String denom = (String) val.keySet().toArray()[0];
            String value = (String) val.values().toArray()[0];

            BigInteger wei = Denomination.valueOf(denom.toUpperCase()).value().multiply(new BigInteger(value));

            AccountState acctState = new AccountState(BigInteger.ZERO, wei);
            state.put(Hex.decode(key.toString()), acctState.getEncoded());
        }

        logger.info("root: " + Hex.toHexString(state.getRootHash()));
        assertEquals(GENESIS_STATE_ROOT, Hex.toHexString(state.getRootHash()));
    }


    @Test
    public void testFrontierGenesis(){
        SystemProperties config = new SystemProperties();
        config.setGenesisInfo("frontier.json");

        Block genesis = config.getGenesis();

        String hash = Hex.toHexString(genesis.getHash());
        String root = Hex.toHexString(genesis.getStateRoot());

        assertEquals("d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544", root);
        assertEquals("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", hash);
    }

    @Test
    public void testZeroPrecedingDifficultyGenesis(){
        SystemProperties config = new SystemProperties();
        config.setGenesisInfo("genesis-low-difficulty.json");

        Block genesis = config.getGenesis();

        String hash = Hex.toHexString(genesis.getHash());
        String root = Hex.toHexString(genesis.getStateRoot());

        assertEquals("8028c28b55eab8be08883e921f20d1b6cc9f2aa02cc6cd90cfaa9b0462ff6d3e", root);
        assertEquals("05b2dc41ade973d26db921052bcdaf54e2e01b308c9e90723b514823a0923592", hash);
    }

    @Test
    public void testMemEstimator() {
        Block b = new Block(Hex.decode("f964daf9020da0a7f0248bfbb49ba21302f9a6dbfabda21de4a59d9ac33e832f406501373aa893a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452bc44d5378309ee2abf1539bf71de1b7d7be3b5a093f9be92b8a699a8ab8f72b8539b307f150e230aab3cf106bc40041cd472a35ea0d13172adf6cab541a651710427c88a92a47f51bb58c8705ca8c2bf6adace555ca003ff1726fd8f2b3b213cf47dafb927253858dfe47bc16060549561f774b8afdeb90100502260304042380280110c240b140002180040200aa4017002998ca01a38a128070a0c04040841494836c0015d8200108b020304810502409a8088000abb8201004000c1044ac093221046ac092c04880600000600080060120a80408a49a40215213020120040022582b98442025a00484802240804006800810219b411201020030028142c00400062002194008442442401c00008813451099620002000120a0051809844320000040250d006c20320a0440d11088000090000000054000201848a0ac08c1011a88092042880a74684a044070008100001815004005860130450690000000005449000800005ca96e0253016025440004200000800030000870a4cc6a8954c6e834e428e837a121d837842ea845a8d16158c6e616e6f706f6f6c2e6f7267a034438c68867b67ef20beef55844105289c21f97f1abd4b0a0f9f49b4f71ad1728896f95450073af434f962c6f8ad8305844a8514f46b04008301a22c944470bb87d77b963a013db939be332f927f2b992e80b844a9059cbb0000000000000000000000009aa154abbeed087fc637b02220f6f9ca1e839afb000000000000000000000000000000000000000000000000000000000009cfb826a0233b1f37a3198f3bedf03c294c41513fe2f755057d50552b8b88cd7b11c19b74a019fe8c087e8261b1258a2a792a450cacedf7d51c72651cf81b1404f4d357be45f86c01850dbcac8e0082520894e46013f9ac84c0c92e597fc77d1b6f5a12d051f58801434c04928f80008026a0b07eb57ffe0f169754266958fe9016ef4b72337f03b95dd8736501963da68220a01e384c1a34b17ab42ef0f0aa3e54834b41561f4b09355c8fad8e13a3ed6a1155f8708304f6b9850ba43b7400830668a094b3408f57077bb2dde0c5515af76bdc33878c975c880ff59ee833b300008025a01ce0f9e7e30e24a883512df526724d7ab87332b554b5f4f609862b234b327b7ca003f5c63bc8e64c13ec4483769425fade4a353b76d9a6c40fd91eb3b2b270bb4af86c04850ba43b740082520894236f9f97e0e62388479bf9e5ba4889e46b0273c3880eab03262a30e0008025a07b859da40ce711bf005d028dc3e642f02f1b8a840ece4779461434060a1bea13a062e59be0a3f252358bce0f8f667c17c3ebacb0a91f9f31ace0cef25f429ad77ef8653285098bca5a0083014c089412fb5d5802c3b284761d76c3e723ea913877afba808026a0e5e1b99e0028be6f807f8eeba50dc2a88d9ae03b2c6e90877a69f7e54c66a3d7a0561055a4cbcdc9d7ffa9b366da54dc942164c2029e59bc416b75e50f12a98f71f86d0485098bca5a008303d0909456eb83949fdf543e8cee4569739d21f07e4eafa9880326774c1c0380008025a0ca5fe5e0ff90124a77e0f4516cb9c46ee80633787c06079bd4d3211fb0e3d330a05ae9853ff257d8bfa6d5f54f5d297588d2acf3174d37de44c044f21edfcf6c35f8a92585098bca5a0082ca609478b039921e84e726eb72e7b1212bb35504c645ca80b844a9059cbb0000000000000000000000009c3e7e5a0e072eb394d75c0d18e10cec5851117600000000000000000000000000000000000000000000000b2ad30490b278000026a09c12914b07c23f1694b9c835e4bcccda9dda0a49377bc8690df1ee199f1944dba037f30add470ca323a924ef085778dcd38ae37e3f86f067fe971e40d4a16f04bef8a91685098bca5a0082cc9594dd974d5c2e2928dea5f71b9825b8b646686bd20080b844a9059cbb0000000000000000000000008401e4983ca4a4a1f1cddeb89c4085b69169e6c9000000000000000000000000000000000000000000000002ce1b2b57de96800026a05e57d944a3049060276c562f8cf704dee9aa2b91da007717e848cc0f012de8aaa007a8fbd6ab346e6478b43dfd573acdf9c166b1f914c81614757a8cb4630b54f8f870830df28e8509502f9000830186a094933bc4e63edfe770f962459b66da5388a32263c2880531d5b3461364008026a04db7659cf5e3db86701be5d204d4229c232d8bc34bd6fe60c282b3e1a670df22a013b5069962e32c568e602571434db0d85b77a44697355d8af54fcb0a81b3ffbdf8718307288d8509502f900083015f9094009c40e9589129974a515ea90c2ab414ccde79ca89056ba3d73af34f00008026a0e75c1b66ca1dfd848668959e4cac392b0c1f35870dbeb2cb6996eedc2f19a898a072764cfb083400808d0d8fbdf5277bb5c5ae42e7d757b0e7e8712ccc6694c11ef871158509502f90008303d090942a0c0dbecc7e4d658f48e01e3fa353f44050c208880f9db9ca32d7600084d0e30db01ca05c73421d0c3bbfc765cad8fb8ac759d5eb8107ef1919d85824eddbd7f02ecea7a077dd3b92923663c8030d0a9eb1c540bad33b9f13c857a801d718b12d5d821650f86b823548850737be76008303d09094c7f7ec818f65459c3a692065fc5f1c52129c893480849ac8441425a0d593908326699956dc84bd35aaa6e86cd4a8b824ece525d817048ff5e4d31ccca0603ca0397148bcbd236cfc0251b3dba50400ae0050d7b050960503a51668caf3f8aa808506fc23ac008301d4c09486fa049857e0209aa7d9e616f7eb3b3b78ecfdb080b844a9059cbb000000000000000000000000692da4782d996dac7d66b5822f3c504f67da849300000000000000000000000000000000000000000000001dd0ed9ba758e9e4001ba0ce3a7a5d0ef258a8518b7cfa4f505415b47d9f311577599235e0a40d243964d1a02ccb5aa80f3fb93f551759237f139c6a77668594d386c52260b54a64ecd700aff86b018506fc23ac0082520894e65a88f487f5d26469cfd37ce7ef763d6d9be45487304a920b74dc00801ba0ca7aa102e2c1edf6c12491f7eeca2763135b43e4efb280566d7fd381cb2a31fda036624504908c0545ef8e9f17ede76b4e41a54a55112ace60528329566ee28880f8708301098f850684ee180083015f90945ca08c42f0dfd09cba09fd94320bbdcf4d50586c881b9de674df0700008026a0707232fb5b62a713210b5829ba560f516c130ed48710504fdca6b68ea64f4183a05a0100cc3b8cc5d07324be52d47172b5ec146dc86ac6f7784bad2ccce8cfccc7f86c07850684ee18008252089486e6df2933f88a00caa11ad19413123c3abef3de881adb9d6629d7e6008026a081f6c734fb3523566f78adb1569c95bef37e2e659335c723c35259812ca0a32ca078dd5577804b470bc295b854155c3e2c156711d11bede02e6223cc6455966345f8a90e850668fd895082f56b945ca9a71b1d01849c0a95490cc00559717fcf0d1d80b844a9059cbb000000000000000000000000e7bbdd9e22e4763272e417cc247219b72422a04e0000000000000000000000000000000000000000000001c9966829aa5044000026a0853b5c66e2a77a074ca76ac16f092a0e2f9cf4c4bb29deb126be7deb6df415f9a015491c274e59b9cc4f8fb909a58ef086bf6879ef71256a5d4df488beef46d72af86c0a85055ae8260082520894053b270864d6a858c809a68c0b00280dff2bc7eb880118c146a62a46f4801ca0afc989860bf3301f538690dc138533eebd3d239f7fb75cd6f7773323af2b543ea02673f53178299e28eb1c5a8be2cfe951121439b272f2622cdb027481a5e1d332f9016e8304ea1685051f4d5c008303f7a0942a0c0dbecc7e4d658f48e01e3fa353f44050c20880b901042295115b000000000000000000000000aa7a9ca87d3694b5755f213b5d04094b8d0f0a6f00000000000000000000000000000000000000000000012976ee0708e4c8241c000000000000000000000000a75fcdf436c9713b3757819f1fb235918749c3ba000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000001c43dc24648536c130879e8927f3adb53c3c9a01cee9379fa14b004846385265306c9fc438db8b8e1e72441e7fa5c463e3eb62c9f5c0457d339961e52309e448650000000000000000000000000000000000000000000000000007cb57bdce51231ba03f4b39ae10286e5b01bc0f6e0eb29498498640327980932cc2e0767c7acf1ae3a04d3ce562a78eeb60ce835a4ddc6228ee104d3edaf9ffc4678586488c888f211cf86d5c8504e3b2920082520894737d60f2490210da0f6ce401e2dadff995ca80058902b5e3af16b18800008026a0bfc3f176f41c6e53135a66b13113b8fcc3e12be96354809475fc719bf4a8d990a07e34b40c5c24a02d7e1e26a43981e30d0a94bc5eb3518268dd4cfe783931bad1f864048504e3b2920082cbd89445555629aabfea138ead1c1e5f2ac3cce2add830808026a029856a81c5fc062e8e2835836c3c57511ec5d7a9869e4a827fe1e1d0392b3f90a02aa4333475aff5acee9deaf748bfee321ecb664da8a9070f56d4162a021adfc1f86c4c8504a817c80082a410943f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be88456213856625c0008026a0bbc22c5a7c90b7a9069d1cb7d9d033013ae28ccb0b60666ded5eefe11d00ff21a07f528d89ca785104becf15f59ff48ee048df35dff3860c05e89156e1b45b9b58f86c048504a817c8008255f09415e310ebf90b07bc44817c4f6c312e0220b81e4e880f8b0a10e4700000001ca04ff7de42037f13e0345617295dcba17c765d5725680414b035756c4ece6a2b00a03bbbcef9953a172e9f3837b3c8052ea3a34726e3a4db17d3e95b9367c6814066f8ac8205888504a817c800830f42409464cdf819d3e75ac8ec217b3496d7ce167be42e8080b844a9059cbb000000000000000000000000ee13c3012681e2d758ea6d098b73fbad1b1ae850000000000000000000000000000000000000000000000292993e7bd6dcb4000026a0e7b18eb3f25ff7ac57ea90cbc32dff69fb93c086ab2d8118b16efa3129baa3afa00f4e426723dc595bbcbfbec3236af2b6ecda9ba1b275b2186fa97f7f8e6d9b87f86c078504a817c8008252089405ee546c1a62f90d7acbffd6d846c9c54c7cf94c881d178d98cc2cf8e08025a0a5b3a3335f8df2d6171c0e559ca44644d64cd8a0073d5d5a580caa0ba8be4f1ca06de00817dff5ce59bcbe3fe34963367ef3192f3285bc975208c13f590627fb2ff8ad8307ddee8504a817c80083030d4094cb97e65f07da24d46bcdd078ebebd7c6e6e3d75080b844a9059cbb0000000000000000000000002571586392956e467b4124def92cf3da22a3096500000000000000000000000000000000000000000000000000000072dbf46a2025a0b3d069846501c4a9d2f6724c41041b5d98fa2fe2edc615145fcfbd5c54605b0fa016ad5eed174c506a1d1c05c4ac168de99459c8febe3477fd3cb47f122c4df1b6f86f8301f6c485045d964b8082c3509437632b659660988d99acb59575880410e2f43dc6881efc523ffa056c008025a085d1e9e7831a902cecbd73820a705e0058f8700e326056de9c58952baa880d73a05326a3d89da4ed1e0a775bcd4830517052de8b10451c3d8bd59d3e0a216b3da9f8ac8207c58503f5476a00831e848094d780ae2bf04cd96e577d3d014762f831d97129d080b844a9059cbb000000000000000000000000fab4b2081dac9fc307dd4eaefe9e92268562a658000000000000000000000000000000000000000000000001ec93f1f8126800001ba0dc8b5bb15c0d6e84ccb4dbbaa690e6199e35260bada02147b77a023e9abe9caea03d736e049525904f3e7bed060a4990a6bf28875f7d27e51c5c33547bac8bb41ef8ac821b218502cb417800831e84809490335e6f8cf5b4b3cc28217b6b2ece290439e49280b844a9059cbb000000000000000000000000ba702b32e37d3537209babad75ee7d318c7e7769000000000000000000000000000000000000000000000006fe3c10875964000026a0f55ec9369d983969c6989184720db22f2a265f2fceff7f774947b0db3bf9d22fa0617af4f0a210df4a599cd5149dfb1d34b5848a5ce6b5b4e1a07d6197f94b900df9033083059cee8502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002926a012ebb3326445e6342f20a9a2e8e44d0b4430feacafca98bb5e46944a1dd8c309a07a0dd3a18c9d0cc1927c7d4757c0522567b7af9e2432714b548bee948fe948c7f8ac8205158502540be400830e57e0942c974b2d0ba1716e644c1fc59982a89ddd2ff72480b844a9059cbb0000000000000000000000005cea26d5c431e6d2c88b32f7b5bf48ccbe4cee20000000000000000000000000000000000000000000000007e651f8215e16a00026a08b2d5a76c394bb10c542bf009724107d0b32f83f5647f030e7664bdb97ab9d88a03473c68cdd3d4d63b9336c49a417894d8e0a69d3959c28062fde00f89d21c7e2f86d168502540be40082627094db5b2ab29b624ac3644e437393ffecf1ff5818028901e5b8fa8fe2ac00008026a0a0c207b23d0990615901a3f4bbc20550b6809b73dbc6f28ec9c63b62f7224df7a05ab4f627471594013be68b19a1ea5956d797571dc6bb2fbb84b01643e0422e0bf86d808502540be40083015f909495153c5e1d9e1c6754e95e92d164373020088d278802f93026b03590008026a08779b66ed23d164aca7765af843a8bc12df59cb83c24795430aca993bc096741a008dd09661fa350e68213b061d88d7fe057a142edb71222a8cd00058dfc02b47ef86d8202848502540be40082520894fa3d425d4e09ec8431f881593f45fccdbcfa4488870bfbd981743d478025a023d60fc1e19fbb54d19a85daa626ca48d3994822f0830606ffac7db72baac9f5a0107a6c1e4cf9a909f8f87b57985d219ea9d8ce7f0ec382c989e2f176e4a600a6f8ac8261538502540be400830186a09493e682107d1e9defb0b5ee701c71707a4b2e46bc80b844a9059cbb000000000000000000000000860c7f15df4165a23fbd10587f30bb5c850bf796000000000000000000000000000000000000000000000000000000009b9c45f025a0c1e5c33fa4cf45c519dd044e0d9b525130201352f04af4da9edf0da71f99312fa04fcc6f9de62b6e009a49bc75e715dd217bcc5ff4a54e0405948b0565d9f2618ff865808502540be400830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808026a0d00295afd845cd81c1259e2e17b5c8d0d2e1e9ae8eb6738f42096aecc89d9aeea064f6cfebdce252978736eebad6ed3b371416b662f6229e25f886c0fcd8bdeb12f8a9018502540be40082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb00000000000000000000000004923c5c744653c78a41a26c443b1e78b9c4961200000000000000000000000000000000000000000000000000000036a7b76cd025a0b0a643ed5ab4138344c4177dd946d50cc060d4a3cfedcfd8642c46197cbbae83a07e93439db7761c5863cede3beffc2e2649e64bc6b3631c0aa61f05e0d98a01a5f86d808502540be40083015f90942c71e8491862e24bf5217673aea600468301245b88031156963dd028008025a0ded7d8edd2562f3165d845df049dffad61e27318a264623522aa6e7e448b1b32a00d76d2248ddc97a4b18874f444c0a34b83c2259ed7ae317a3e3071baf92d51d2f86c808502540be40083015f909416bb92ea0de563a97d2a9252dda4764d06c3e89b870c04c66d0afc008025a0f08ca8cfc85c5bb19cf9765de3e38d154e0c8d63629d58b481556a7dda0bb971a057d9e7f09903922727df0e13fc22889710f3dc7eeb991ec2a3b90596f436d1e3f8a9028502540be40082ea6094b98660a7784c494f34ec6ee343499e2d2c47b12880b844a9059cbb0000000000000000000000005296eeabd756f156eecb68a6a87e046be56f91cf00000000000000000000000000000000000000000000001e162c177be5cc000026a02b846ffc5dedfb0d60b177e5b310deade11aaed4d463884764726d2a52613168a06bc4381887b0dcc86de234c12ceaa248d231a618f02445adb3812a4cc7b4c807f86e822d348502540be40082520894f37910f86d5a1fbd3de7f7d6089c54c0390f8b628804a03d81c58f60008025a0ee4e35bc83212404e299ab15919858db1bcbc7ddf2d6a3753e2f701062ace231a02d979b9de92aa251642c300a0ef7dd78a5803a355b7f92efab8628812cd29ed0f86d808502540be40083015f9094bea97ea3ff568c553cdd4fe98eaf5a08e4fc484088119fa980a91e1c008026a00ccf7a44ff4aed3052f8067bce0abe5be8a340ef81f52ff6fed78802175243eaa051e39021e9cc5e5d8edfdd0bc77f03b74fdedf1c811d5b044d3faf9b6f14ece5f86d81938502540be400825208944fe6fc250e21e29820462c856891d5cbb1a5984c880e92596fd62900008025a0450e58ff000fd6993db264e38921b2d89d0a8f12162b6b74471a857eeb152ce1a076a046d293bfaa1e6d525154ab43dd0f3a64aef9ce1b8f779c96223436248626f86b098502540be40082520894be7bac1c616df2bfec24dd1e083c47cc03ab319887038d7ea4c680008026a037f0f9248fbfb2f9977f1ad7f2794c13670e6c68892f20175b11292b82a2e471a048a886b22bbabe8f8aee9d72b4d6775a149d7b6c8cde5def4f5448b3a36f7c18f86b808502540be400825208943b61cd9539c7adb09029590eb2134f50264c0fee87030f132f26d0008025a03f3b29668d917062255742627381a3be53789c93b82a0b1787dfda49c1ce0e7fa06be0bd05ff3e09bb86453f20c814088ec00af3c7445c4d756a082a3bb4eccdf5f86d73850218711a008301117094137822b91c6451762e036c529c33c64e94e9c625884563918244f400008026a01d1c69c6f1ab3a13d4c31d380c104c5f265878adaf0ad9c19b53682924941adba064a85d344d9c6c3aada6b69c60eb4004d8a6892f5adfdfffe389c69879b97459f8ab820a1b8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb0000000000000000000000002ee8c7ace08ba528c0a17426d5b32af7bb59efdf0000000000000000000000000000000000000000000000000de0b6b3a764000025a0825d5a8b86f3c83cd075318c8e09eb560e8fee2c9ed2c17c2e11550855f38bafa070b8e4432c714377df5bc1779d12c019203456c8066a2b0fac72f8a495963becf865178501dcd6500083011ea29445555629aabfea138ead1c1e5f2ac3cce2add830808025a05f91c347847d091eb093680a922170cc5594fe1572c60fd313d4310a7b3b2234a07d961331105de03d1320f9bc06dd4781bceec8d12e77fa2b3155776d8f6304fff8a9018501dcd6500082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb000000000000000000000000f9ac17f4eda48b0ac0bf7baf2d09eaff37a62ed6000000000000000000000000000000000000000000000000000000000000000026a065bf2cfee714276b351ee713cfd119d6235b771a4e10ff97990f8fe54ed9d7f2a056b36888c9f37e63df49c06290937047c5a6526de637f4df5eb23cad53475262f865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808025a0767806eb1a58d2bc390531310376628b533d156c19c89791d5e8a387b5cebc8aa071fd413b5052ef60ece9d474d0ba88f9d94d5b2ae47ad6d0d638b83a38353aecf865808501dcd6500083015422949c821d1eed859080c307e326fcc888c230d2bf86808026a0df03333e11fee3c55609648b6a7bc2507b33678938f23b87d278435666c9d586a010fd91a15a0512c05f34c24399445d0e60af1bf581d8a31b64b7ff986dccbec5f86b188501dcd6500082627094878d7954c16f6f0aafdda7aa5dbd825cb50281ba8725449973b1a0008026a026ffa3b09d46f37987debcb5ec81d27e317735c28d0bf1774bc4da33e20e7642a014fcedf54797ed1051afaa488cce6b0295703bf158585604953dfe63cfbd4119f86b378501dcd650008262709480f8662b859e2ad3b5e7feaaca716ab3ecec800a87044364c5bb00008026a0bb20d28877d03f4f623d09fcc7d4ddb2e522e5670bb70300ce857140e275351da06c298ae62ba525c4864472dfa0cb005ee7f408056facfffcfee53624a839678bf86d82041f8501dcd65000826270946e92d5b6f866986bb38ae1d6d8d749c437c158b08703e871b540c0008025a0f8381ce353bc914caf0aa8b8443d09bf5873510d90d0f3f7b6a5eefe7f5629eda01bc402fdf8e667e91fdadfd8470e1f83acdecfe7c3732ce59bb15ef6642aae7ff86b498501dcd6500082627094defffb1eed8571ffc601e7114f626bb1ce8e01b987044364c5bb00008026a04994d82ae686511bde97390411ad41aaa431da7b9010b88897bb31ec8cd4b9aca07b426f7d9dfa2e67a96c48ab9975715ccc9a09fe230ebb5d444a5f307268a45bf865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808026a07d2577aadd023057ef2ec01b997390c3fa2dc22429d1903f13b700347024c32ca06f37824c896fab4ae721e87d85735ee0b673f361e86468cb778cc547af2b003bf86b058501dcd6500082627094d550552430a5a9c2c7e9dd3c2f042b72e0181cb487044364c5bb00008025a07841ed68678aabd69c13ca18d9d2fd7fd15f8a24a81ea1019c9b3f7db1d3c44ca014e076bc30b3e67a702d2a707b4816da89654a8ea48f58c326bc896e2c5608d3f865018501dcd6500083011ea29445555629aabfea138ead1c1e5f2ac3cce2add830808026a03a78781565c6deb9db3256151c0d4ee6fd9e9c6167738b77c4ac5054b65bc26ca0724cedc0d77ba1971c77b096131f79127bf5b17d77c329493bbce342049bd190f865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808025a022a0e74b66fe5435d6863f4f54e3e818ccb6a1fad444d6547434189ac93a76bfa010223854280edca930e916ac8a5063a3eddf9fa827426535e2da306eddfc139ef865018501dcd6500083011ea29445555629aabfea138ead1c1e5f2ac3cce2add830808026a08658358028c1daa5af9ccc69ddb8907eaf141f1cf85af74bfc335c50e46fdff0a0615fa95dda08f087d2e0be3696c4add62fbc3c601b3aeb480a0418f6842eac98f8a9018501dcd6500082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb00000000000000000000000085b1af16abf053364284207a8b4180b9bcce54850000000000000000000000000000000000000000000000000000002e24ccfef026a0931463dc408eed8a294e3a9cc5b4e07c07b595e9c1ef9741e203929e72fd2672a04be66179d4fd07b8265d03085885c541ee546e0c8cdba030d34f85958813fe28f86b028501dcd6500082627094131f4d14341e7ac99ee99af4d0af03ae6b1e11a48729ec09985980008025a0ad4da4ad9f2f3f50dac6fbab36198f3e77aaa44c5089829dcc2ad63067377fdba0050fb9099ff87702520e9f40e39825ca9af42db837988ac301bc6a5f04df1d80f9010a3a8501dcd65000832dc6c09456cd53067e5acd557dbbfb4c66580dfb9722962a80b8a453047154000000000000000000000000eec23ec894f2fe3879472861da6064e4a4dd715a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000094a6f686e205769636b000000000000000000000000000000000000000000000025a01c4c38cc4bd08b460cffdf0c77218d10ef90e7eceb0456c6d1d18dbcb6dda981a05e0d3f06396e2c89ae000e8ba228774054888a52aa3b65e4b45a83c7b052b7e5f865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808026a0848b074de4ffcbea27e2ea29632a5188bb4a9475928b184a509b5f7f32d7e336a0239b7abe6e53cce99b6ecb5d2e2fb179fac53b9750158b563895414a3139db37f86a058501dcd65000826270948d94432f09d47b07f16409dcdc89668d06c80f3c865af3107a40008025a08db32e28dfb01e7f4b78d7e97ade00db194dad14d992854fe2873a5a074b2160a010408bba59e242162a276945185f0cfb2e2e9679a7f29493399df8eea3b86419f86c058501dcd65000826270943c3c3ca45ad57b24b64f72d570f1bd0e46424ee0881bc16d674ec800008025a03914b8eb0a53afbbc1c4f52c5d8d902a83025818b3149fda8460b9fcc5eedd24a05d6acf8b6f45aa723d1bdcc6f8fde115bc4d4ccff0e1d1e0ae43d368df8e94d9f865018501dcd65000830188ba94041fe8df8b4aaa868941eb877952f17babe57da5808026a0fb92d03e8f6c565e099cf9f8ea9b425ed30b800c8c98a60a75dc21e017e85f51a01602956fb3dfe04def18e8ac26cd538aa2fabd1581accf17e7c4685899ce8f4cf8a9048501dcd6500082ea6094041fe8df8b4aaa868941eb877952f17babe57da580b844a9059cbb0000000000000000000000001ecbbf170219e1a6855d0529850b5e518c78e2380000000000000000000000000000000000000000000000000000003a184861e026a01a69934d2d8466e196f8a5e366d444d8729730f57e426d7f8347b6ad46e4abcca01ff262d01953845c12f89d7ac1b12b29241b18d81e6d0c75e5eb68b98621a4a0f8a9018501dcd6500082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb0000000000000000000000006943adb55f9849366cc51741b1535d596c91784e0000000000000000000000000000000000000000000000000000002e1e3e877025a02dbd07ad96b2b02d7c73973a2ec45dcea415d01155c54d1e490fb70d13e0e3b7a06c93882133cbccd591ed06376f4f8dacaa478f884d243ae26bca23779f1d4915f86b028501dcd65000826270947d2337f89b641d9c5ef8eb9ce686750f3a20dd64870d8014722580008026a07a0a88e6bef92235d56c733fe9c7b497212e6dd37bc299d52d13d28c62fcc0c8a03467a9dea1c4f482d047f9ca5f3531e41fbe8e51f083168761a996bf0f8ebe6cf8a9808501dcd6500082ea609420e94867794dba030ee287f1406e100d03c84cd380b844a9059cbb00000000000000000000000061652ac9f52bad1b9d2b9833d54d88182a5073530000000000000000000000000000000000000000000000821ab0d4414980000025a03e55b84b41093367bb8bf03590a58365b8340c1e9fa8e5bc20848a362fdd1dcba03697e776bfaac2d870ebca903daaccff004f4692226d9c54d368222e126fac94f8680d8501dcd650008301a1bf943618516f45cd3c913f81f9987af41077932bc40d808439055172259f8fdb3b77253d6f7cf3f36ee0ead450c39aa3044b37e01539b6efa13f6aee82a05fc31294d0bcff616477caa91faa54ec9538a0d50eafa95dae08a4c62acd4811f865038501dcd65000830188ba94041fe8df8b4aaa868941eb877952f17babe57da5808026a0e6e1a06e4bb30fe466bc7c5ed1470d6093c9cd18a4f1b0f17e4939fd7079e734a07673bb62b3129caee22a8fb4e26dd7f727061a6ac845833ccbb23add328f9c83f865018501dcd65000830188ba94041fe8df8b4aaa868941eb877952f17babe57da5808025a0f17d8db4cb69da7e00a5c8c543b3b403602a9b78f458615cfbead6317360340da0793929655871a0d81d5f64151526deb1b769970160f9554457652baaa589967bf8678201448501dcd65000830249f09445555629aabfea138ead1c1e5f2ac3cce2add830808026a0ab499b2473b857f9a40f4ec90bc5c04b16825e7a2d92ee445534ff4eeabd3e0ba060c7bcf537b0d55c14e968449a3eb938f871dba0a78e4fcb1dce91ba09205334f8a9018501dcd6500082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb000000000000000000000000297e4a2a65b53d57659b250ae2fef7b57851f5d00000000000000000000000000000000000000000000000000000002e211af37026a03060b1f66c92579a8abbbc9fd84531586909c6666e385479726fb16e88348f72a069ed6630d96e1e9bd133ccc3929e1471e60375b1ca9b27fc30da44e4906a6063f865048501dcd65000830188ba94041fe8df8b4aaa868941eb877952f17babe57da5808025a0c04ff31100078fea393437bc326421ca10b85c3a3712d15c4e4fafb278ac7107a049d1f082e0d3627e56630657f0dd2bbbe5a30ae6e05d441b0f732445966bb430f865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808026a0b18e5ab1569e09a1b51e0615d98fc67ed475859fa7e37808d34963e316fa581ca0644d546af52528fa6cca893895a059a2c41829afc6590c83aaa30b18f84bcf63f8aa078501dcd650008303d0909470a72833d6bf7f508c8224ce59ea1ef3d0ea3a3880b844095ea7b30000000000000000000000008d12a197cb00d4747a1fe03395095ce2a5cc681900000000000000000000000000000000000000000000003102eb135ac856b8001ba0824921bdf2549600ca3e4926b6b6118ec838e80e61d25f01d606192c0cbcdd97a04c1531ba1db290020244d1f0efd026c401b468eacbee78565d270129614df997f865808501dcd6500083015422949c821d1eed859080c307e326fcc888c230d2bf86808025a014eda6b30d89a40fe9cacd1f3f0bc18ca50428dddb974e9b5dc1619e86efbd84a04fe40e4abdbe8a97e08a52a2dc11c985889ad97e89d1b2154ddfc2075a4be5c4f8a9058501dcd6500082ea6094041fe8df8b4aaa868941eb877952f17babe57da580b844a9059cbb0000000000000000000000005ffd96366c0d3ea6d8fa2f91223d65d52cedbd710000000000000000000000000000000000000000000000000000003a243423e025a081715992bf76a845033dd4df3ba659e714a6335f217738027bb6142cddf33c32a006196b965820971a50d35065a27ea3f37799f1b0f6196f14d44a5d0961b1579bf8a9018501dcd6500082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb000000000000000000000000285049ff70c9acd36b0829b1364762e25df830120000000000000000000000000000000000000000000000000000002e1d4bc30025a0054c26bdd55b89cae30fdae5446bb6b479ea3b4c3e89376940b39dcea1450f05a03b24ce62aeb16c20b1f4eb35d04b6caedeaf3442c6939e91687e000b1fce1f5af86c81c58501dcd650008262709420021f82ebe035557eb44b42a4ed201cfa046d3b870775f05a0740008026a0b828a3b0c3f6fbe26f53f7484994dfc32f2a46db65d45f2f3e18e3689d067646a075218ac434f9b3df83ec4ab75f4a13cac02b8f3482e970c7e00dac765c8e43f7f865048501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808025a0d73c2c97b88a1214bfa6b94997d019de6e6509db165523f11da5d5a85ddb0453a0448dd5e8509b51effe195c4ac7a932c48b8b2afcfaf1ca9904418184da41cabff8a9018501dcd6500082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb00000000000000000000000094e6dffb38cade4f8946176479b32c9444969ebf0000000000000000000000000000000000000000000000000000002e28f91c7025a03d34dda851947973c1fcaadf818f2c564ec442471ef5847b9a8112f2eca53543a06da49c7d9e58546244449a88854070c33b02f47991cc3b38600a35f9a4f09b1bf865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808025a0d41c9093a124f7d43b98e63b57da3319f0b3684c7a4ef477f13b95d21a99c9fca016698d94f95f351d985746134b54299b568bc1ee9485bc417bcf0ae1f3027874f865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808026a056670ea85d93fc362d2d97817976a4c09ebf45df30fa408994805fd7f3364311a0325607212adaa85e51d0a525b637339a7155279646c2c455367508f302a1eeeaf865808501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808026a084c6ca7c20efd06f116e4195e57773fa95254ba65d8db3d940b6cdb04c32fb98a03d62df0104c0be2aab0eaadafc0a15bec508ab4471ec607734338a0665a92ffdf86b028501dcd6500082627094e8a92b7f5b1ca356e42af878ba0a3804f30da5fc87c85667fee260008026a0cc179d1682f27ba3462fc467c3aae7d84f414dc933d04dddde24fc6f164ea17aa06620fa60bf3645f85c6f8338751d71cc093a69bbb88bffe60bfa18798d4fdd4bf8a9048501dcd6500082ea6094041fe8df8b4aaa868941eb877952f17babe57da580b844a9059cbb000000000000000000000000a26606347b1ca55695781fdf9bb97b1bd5e7f7a60000000000000000000000000000000000000000000000000000003a20c6c28025a030fd5263601d0614e11f3368f0f53b5c3b17fa3cda2ae3140792d45675d5bfeda01a129961517a13116fb249d0e0d2108bdac5e955bb84fddd939cafea1e34226df865258501dcd650008301adb09445555629aabfea138ead1c1e5f2ac3cce2add830808026a0adfd88dfbbae0604764fb248362dda15ff70251b2e9dc196953fcbc9a2a6aacaa06f253e0b0438c495571e02b315cbebf18c2b654aa63fab0942a82640a1009226f864028501dcd6500082627094275b69aa7c8c1d648a0557656bce1c286e69a29d808026a0ce76e53b280e96e399a694251b01cafed48890a22099239f75e9724c934af85fa043f2a2c351003aec48a6a80786a5d955be65ebbd5e965cfcb90e72b2c321cffbf865038501dcd65000830188eb941530df3e1c69501d4ecb7e58eb045b90de158873808026a0477492d12369fbb1d979b20ee4ec6b65b2bc609dca95bf40f091d77d63d795e2a05f6c9cf205a20a1d3e8a67f05f0a7ad04f37d4cfe69292cdb475213a3ac166d1f865018501dcd6500083011ea29445555629aabfea138ead1c1e5f2ac3cce2add830808025a08e35620e56bd5246b14d30955a30d60284ccf52ab3bdcb2595a14e344317417ca017f78d258350cbff103d92053f932c432af31e03748a11646ded8b2d13cfe95cf86c0a8501dcd6500082627094e9dd33253476a52f68036b03c5fe19465999d639880de0b6b3a76400008026a0e480e36da4c11371298833fd2edab0c4ee2aa8acc6bdd14f9daf0d211e24a5a7a04ef1d2f6e98ccc0935bf190aec550cc63af5162ceb9f869d8876181ff0e2b456f86b058501dcd6500082627094a3543a59ef459d512ee17c663024f3f89dffbcac87470de4df8200008025a0ccc009c9e617851612cd4ede7a5012c3163b6961815ec24a3d2edc76553725dca04296d1f5c92f78fdc27429c6fcae5e8d884d714c83067f2b71ae863a29bf371cf86b2a8501dcd6500082627094480ae00f320a90b7f0e79521cc4e8bf5527ded7787044364c5bb00008025a06e4630fa99b13df833b075ee4ceebe287bc1cdd3d95357053eeba503655337dea03b4bc3e6fe72d77f6dd2400e24945ffc24017ba362785511986733e2b736d5f9f865218501dcd65000830188ba94041fe8df8b4aaa868941eb877952f17babe57da5808025a0ee20d7430fd44bfd6edebcc005cfdb157edeb435dbce04c0f3978721c1eb450ba007637fa44c4925203536b02f46df354f29c56d92015d920b9d8e97bfb2f5bd93f865038501dcd65000830188eb94f7dca20054469a1d548b20859a100b9ec6ff1f61808025a062a7a1611b105ed26090edf659fa1784fd04da136b54d55f34abf4fd1547903ba06443c369a2ada0edfcb706d2e672867e418eeaebbbb2524ef0eed4903c2c1f9df86a028501dcd650008262709471a1a75889278820ea73ac45930ae4ebe5013d4b8612309ce540008026a0625d20ae39aea4cc31665511d5423b7ed6692465307e18b19a625b6d9dd70518a01905fdf82657f8c9ae9e986e0d1695dd691e08993079141015f90bee5d9953a0f8a9048501dcd6500082ea60941530df3e1c69501d4ecb7e58eb045b90de15887380b844a9059cbb000000000000000000000000c328f30cad4f14fd2e80cb7fabb444ab36521d9c0000000000000000000000000000000000000000000000000000002e5b47606026a02090b02053fecb987465a656106817f76e3989bf3bc90882e57a9ae885247f38a07d5ca3fbf0a9451e12c70f14cd9de45a3c327a5bf176b2a297311463f2d416a7f8a9018501a13b8600828dd5943a26746ddb79b1b8e4450e3f4ffe3285a307387e80b844a9059cbb0000000000000000000000002b6401fbf71effb2edc0d419271b7e3466130d01000000000000000000000000000000000000000000000000000000009502f90025a0cadba085ea9d933fba063d0bccc0f8d4a041cb4cab0aed0a8382dcb1adea4753a051ac59ec94067c37b4f997163c95af8c986dcab316e06e946c6bf295bfb2c880f86d0c8501a13b8600830186a094fe7fb69b43e5d912c0af2547d3291864254d4b2b881774160bc66900008025a015827600b51aabff9eaefafb5b9e1cf5386b9a14044b6d0663c8ca098de5cf97a07bc7a99107ea82d31e32c9cf56479b6a9e2d1d8c71ff1c52ea70a21f096fcaedf8652e8501a13b8600830249f0949c821d1eed859080c307e326fcc888c230d2bf86018026a068098f560e4c38f05c88a37d3f3008bb350380f117e292b983e2404bf02b5f67a00178e4644acb2d3c2d7be66fc318917c6dea23f10cc26432d0e0dae64c67a3f8f891818a850165a0bc008303d09094b1690c08e213a35ed9bab7b318de14420fb57d8c8711c37937e08000a4454a2ab3000000000000000000000000000000000000000000000000000000000004453d26a0904e0bc877f87df103e4c71ce23d689b80e585d803c982a384871d3dc2ac574ea00e1aa5df6ba0af2f3f5a8feec6d9181947291d80c3cef19cc74f722e38bc21b8f9018b0c850165a0bc008303d090941ce7ae555139c5ef5a57cc8d814a867ee6ee33d880b90124278b8c0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c4f89310dcc0000000000000000000000000004c251de85ad3498c5b89388d8efc696ddd0b0fe700000000000000000000000000000000000000000000000821ab0d441498000000000000000000000000000000000000000000000000000000000000004e63540000000000000000000000000000000000000000000000000000000037535952000000000000000000000000000000000000000000000000000000000000001c589e03657e41e05a0e386be971c3ff3f24e9a9ecefb176e29ce26c68bdb298a33fa7414cb54cb89afb8d40f04a5a69ba4aa14bdef016fd68d56355c0d54364561ba0c8c60ae751a38116679045d8b1760b3dcb0f6223a9d69b51114f4f63dad4d7dba04a1084ba5790b08892a8339afe0cf20332cd0c99252b94cc12eeda5970934259f8b3820b72850165a0bc008301b54f9406012c8cf97bead5deae237070f9587f8e7a266d871c6bf526340000b844f7d8c8830000000000000000000000000000000000000000000000000000000000081531000000000000000000000000000000000000000000000000000000000004a6b825a01e6eecb6467cfd4cec83c349392e5cba97170cc20d89cece0bd0156e307f3789a074926b4aa0a2d8b3ed69d4a7028e84066f02e9fe65be3a659d4ec35b65e8a909f870830df28f8509502f9000830186a094fefb07a2f0f161994bcad68393e96772c21794be88020091c1e30f44008026a0d43f9003b351e5f08ee41034d158d9916bf41325ed3ee8e2e4d23282a10ac069a00419c3fb210210530880b357cd267d4c4865f3374c999fd046b84452398998e4f8ad8307288e8509502f9000830193869441e5560054824ea6b0732e656e3ad64e20e94e4580b844a9059cbb00000000000000000000000069964ad8dd235535288df785e8f7a450f5912552000000000000000000000000000000000000000000000000000000000bebc20025a0210b8732c3b847d870fa47c16d7e1d9b267ee1e46cdeaa1e7314bf4ee624dfa8a0566c5a6cb04a74af926a812e000eb875e425960e9b07371005754a2539b8e992f87083010990850684ee180083015f9094811a27c1b32a1c265a909ba826a6408f2a35c5c8883782dace9d9000008025a05854558634b7bdf9fe0346c6adb7b9aed883f9e14ce5265d0c28d05bcff99853a05d7e572f5e045aa2f2c9857aa9c21f270f2598856a6860b536e7974f9603bbdbf902ae8304ea1785051f4d5c008303f7a0942a0c0dbecc7e4d658f48e01e3fa353f44050c20880b90244ef34358800000000000000000000000000000000000000000000003ba389df387ff6c4800000000000000000000000000000000000000000000000001627c93273beb2640000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000004c31756a00000000000000000000000000000000000000000000003ba389df387ff6c48000000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000f6da3bc686c810000000000000000000000009992ec3cf6a55b00978cddf2b27bc6882d88d1ec0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c91674d315cc89ba9d6ab194bd0b812bf750cae5000000000000000000000000c6b7d0789d9dc186735d83024c635b0e9a8548b8000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b35ed1bdc59fe1f965e48cc2be1c48442115d8c0bd15f1133d39986b34769e891062f86dbaef0f0f52d4b37c14a5da2eb1d85d60546a39086c277f87a31c1d39bc6bee6576b09fc4de1954b6fdb31e5b6d5fef0710960977c824447a6175e40c42f4321568697ddfef8cc1b49448e764e9fbb304686ed294dc0ddf970b61afbe31ca0a0f7194cb51c0ba628c05e9fd6413a2b73f0251884d7f286bd5c3329b8545bf4a0537ade4b71462b9608f429b33c905f8e304ad3c5609051c5894fb6c059c213daf9033083059cef8502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002926a0642924aedbabe87fbc3f9189c0926313425aab11144fce53f6410eb8302225b8a049723bf79ede4f45182466b34bd5a5979a269a1b098ca352d14e4ee583155ea1f8ab820a1c8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb00000000000000000000000053587ba1e1144d03a5819d5101f94ab0600fb4f20000000000000000000000000000000000000000000000000de0b6b3a764000025a030b21caaf789d4d6fccf7b2b504e9fe28d78621e1c3c97c843447a1da0e6fc0fa07aac66eb4346ecb120b2ac262b7a00e8a296d79870d3d65d424bcef3fafabab3f8aa088501dcd650008303d090948d12a197cb00d4747a1fe03395095ce2a5cc681980b844338b5dea00000000000000000000000070a72833d6bf7f508c8224ce59ea1ef3d0ea3a3800000000000000000000000000000000000000000000003102eb135ac856b8001ca0fabe31e791c83093ba302cc0f0245015ab58c68bdfebf18adce487e9769a142ca053599a2ddb513f5e004c6acd2e76b5ddbd6994757cf979e87c0a4b8ae94a7362f870830df2908509502f9000830186a09403c779e9b0277310f5347674f2f7fe1897fd3b0c8806ed3fd58500d0008026a0172f976a8fac2ded91b87ea888c81933efd9197069556bcc89bef3fdebde444ca00a1a5dbca5f7c5fb5769ec49be7066ac347295cd48802e37585b2f23e5ec21a9f9033083059cf08502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002926a0b96d8d3220fa13515f9c9ef3dec544e42fdb5f541602f12bf4eff1fab17e13a9a051c7b6723b49b6f4a3ba196ff57c324455fd5dfc9497c2a96b6a569aacd07231f8ab820a1d8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb0000000000000000000000004949da879392266ab412dc0897115db66aeb20dd0000000000000000000000000000000000000000000000000de0b6b3a764000025a08bad8678c23c3f580b4215ab67668d071898ac96a018b7ee0576fa8994868894a06b44f01a4947bcb7cc2461c73c663448347c5369e1c982d07a9e612fed669b56f86f830df2918509502f9000830186a09422091806f89d266afbbb1c22fdf6a5354d649075872008bdad0ea4008025a0bf95b3c1308097200fb39558b44721a2525fcb417ce4e78cf49e8c462802045fa059ad4c267320eba469d92b25a5e6f9b28350fadd44ea37fffc53233675a203b1f9033083059cf18502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002925a087de2873f51df7667488f118710e6e31e8f94a950662b17486baabb0843c6f74a01db4acea166f0621d89e5096ac96b0abc561ada3c38c304f757d066d4afea672f8ab820a1e8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb000000000000000000000000af733e15beace714ee335cc1b81ee7a5153def620000000000000000000000000000000000000000000000000de0b6b3a764000026a0951f9ba9f22863ba96483a1e72bcdfebfd6cb282a88b32bc25d9991c1155b5c9a04f6b3005b1fb6b84e15880561a45aa7426aa6aabc0acff286f92fde899556e43f86f830df2928509502f9000830186a0942fe8283062fc30cb0bed18408ace49d8adccdfa7872030d285c0a0008026a0fc5b060da34701b884dbfaf04d78f49599cc1fc9d5256f15f39c101c1488f192a03ee91184d7ed01242456bfecb892ac45240c083fea7e11ae46cae8db00c01764f9033083059cf28502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002925a005974e86452eb8a23e1f89fafce732d7dd1aea9060d31e5517d47c42d0630acca07447ce67592b3d29dd5736186f4c5a509013710976fe78e43e765e36b6e6441ff8ab820a1f8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb0000000000000000000000009ec8b099d4b766295e8fa44423f228c2c293dcd00000000000000000000000000000000000000000000000000de0b6b3a764000026a0b2b960146500680200383e219d612efa1886e36c49147fe8a414b1db1636cb62a067c85fd8971110c87961ba1c96887efa838e7acef3ded44b1232fc0f3a168afaf86f830df2938509502f9000830186a0946cc2e200c58d2280ac0d0c2f50350bb1f466659987200f32c608fc008025a0676717fc06167d628b197c80c4b558ce597856ba3260caec436bb9e25e762b89a0710c755ba691e3b04fe20e85f644633affc30514ca4f2a9109261a834187f790f9033083059cf38502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002925a06ed8fbbe361c6b3664d8d20ff5ba00f6ca20de8a5a5629d90e6dc102ff4b8d58a048ebfb81610f9256a975c6ea1774c043a5e0251084a890b1fe9fad626129b694f8ab820a208501dcd6500082ca4f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb00000000000000000000000016b50005e6e463107abd5c1342f06590cd871ff50000000000000000000000000000000000000000000000000de0b6b3a764000025a0e134eb6eb936034bef58afc25fa0775556cef2032dce73e34d30f7a8a136d381a017a1dd92b25da2d1927809ddaef71b2d9cc7deb7e556ad2bd85804bc8299af7bf870830df2948509502f9000830186a094b21ae44f4136a04ca7d0c9ede7a5a5bccf3197898829a192fa2d014c008026a0151021ae31f035402eaef55ec6aaf10c6b7a6131338cfd0c35ed6d323f80787aa07167bbee65f1fab34ee097fe5798cd6a497a9be35eac4ec81de9ed404706ffe1f9033083059cf48502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002926a084927134839f43240baf45f18c42938ed61e2d9de4adc0dc8f37bff01e0993e6a02a9db9d8b8062a6227c74a3cbd3344e789c0e7a15573a34008057253bd18c90bf8ab820a218501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb000000000000000000000000dd0ea1397cc744c49e26f2ce569e968569cfd4610000000000000000000000000000000000000000000000000de0b6b3a764000026a0b876183777d985188bfc2634f5122f474ba1ff64cbdd7e9f15a0eccd4d501dd0a0539ef3bb823780bb5284e3d2795e477b40bee2331c014f7849c289f7c1e2e388f9033083059cf58502540be400830e57e08080b902da6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b61029e8061003c6000396000f300606060405236156100465763ffffffff60e060020a600035041663395ede4d811461004a57806383197ef01461006b5780638da5cb5b14610080578063e5225381146100af575b5b5b005b341561005557600080fd5b610046600160a060020a03600435166100c4565b005b341561007657600080fd5b6100466101df565b005b341561008b57600080fd5b61009361020b565b604051600160a060020a03909116815260200160405180910390f35b34156100ba57600080fd5b61004661021a565b005b60008054819033600160a060020a039081169116146100e257600080fd5b82915081600160a060020a03166370a082313060006040516020015260405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561013c57600080fd5b6102c65a03f1151561014d57600080fd5b505050604051805160008054919350600160a060020a03808616935063a9059cbb92169084906040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156101bd57600080fd5b6102c65a03f115156101ce57600080fd5b505050604051805150505b5b505050565b60005433600160a060020a039081169116146101fa57600080fd5b600054600160a060020a0316ff5b5b565b600054600160a060020a031681565b60005433600160a060020a0390811691161461023557600080fd5b600054600160a060020a039081169030163180156108fc0290604051600060405180830381858888f19350505050151561020857600080fd5b5b5b5600a165627a7a7230582046378ee80aabd231215e1636373ac5eccd4f45b88b2a03d6fc70c9671e4802a0002926a0b2e65cd39820b9450cba6b6a52e5d68231bd6b7c75c3fc0542009fdc29ca092aa0317632816e88e1c8c25af20b86e374251b0ad3dfc3d59829e56ddacd0ca2da2ff8ab820a228501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb00000000000000000000000047089369db79cde40279ec52a77370e1e23c35be0000000000000000000000000000000000000000000000000de0b6b3a764000026a0e4b5971a9589874ecb421774c9c8cc9160ab8dbb1087bc0535dd75b41848e22aa059305c7c2eb6bd5637933af1da6dc9cd270ad764b9e0edb2becfc517228274b4f8ab820a238501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb000000000000000000000000f4ae63922475f9e7fefc03c788a0acf6c9788c770000000000000000000000000000000000000000000000000de0b6b3a764000025a03c630f0858b8e658e942bc5e86e91a988ce18bda2828cc33f219a8f3a3c93342a0256971ff6264ccb39e5e49ef9a873d30a0079841fdb9cf155a58da0bc6cd84f5f8ab820a248501dcd6500082ca4f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb0000000000000000000000004de06deaa4f48753167229b258fb9b8400126d0f0000000000000000000000000000000000000000000000000de0b6b3a764000026a0ab72b91539ee3a2e7b0de0357784c78c38e82b4361e5d3af082c2185304c787fa00b16bbd40f5b7b32e71842b57fbe7829501161c62b3b24da4f87022ec8fc221df8ab820a258501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb000000000000000000000000d57a83e33c37316b49296d19fa2877c734198eee0000000000000000000000000000000000000000000000000de0b6b3a764000026a0d57829b1dbf307cefc07a287961c5116c807b5f81216cac4e5425381a95fd75ea00758d5963b1de16e6f872457d77c27128559cb4ceb977e92b11890d5a8dfeedff8ab820a268501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb00000000000000000000000089997319c1350af9cd24a84fd41f6786bdd985b00000000000000000000000000000000000000000000000000de0b6b3a764000026a03891a150e5488b9c16e14d7bb66ea550029f43db91310ac5d8e1c5a416448e5da023be5ead4a1d12114f3fb6d9f58271903281df05f7002f07dfb0fc262ea00dadf8ab820a278501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb0000000000000000000000009fea9854d48655d830d66819983a1793430b2b590000000000000000000000000000000000000000000000000de0b6b3a764000025a02e53fc2de677cd051e954d9ebec9ca7db7b248d39e7432bc397546fca21e438aa0750010f13b411b3d5bf80f936c2201ffe075d7d6755dbec68489ca2f6fe6084ef8ab820a288501dcd6500082ca4f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb0000000000000000000000002bd4af55f12b86e1f2f00068d92ee34fe1d2f6c10000000000000000000000000000000000000000000000000de0b6b3a764000025a067d7b75c838db2ea807e1060ffedd61bfefaa8de5a84ebb2a586a7442f4ca190a07128e74bbb58a97b857fd2cf364c2885d6e35cbc8d0df9027d08198694a6e4d0f8ab820a298501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb000000000000000000000000238ad34dcd7f049a8a85aecdb6b6a18d094220be0000000000000000000000000000000000000000000000000de0b6b3a764000026a079fcafbeeedbecae31a70e56c386c2da78556b6e8d4370eed1da85c2c3da8130a00e685d3a5afda668a9e89764eb1225de3ee4c510ae0fc550d3aaac5d635ed65af8ab820a2a8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb00000000000000000000000006381059d6b5db97a8c73ad668973d6e85a6de840000000000000000000000000000000000000000000000000de0b6b3a764000025a08748f823480daf9ebfd9ec01463ec22b825e3c37ebba48876005c01d30450428a005fbfdec03fc8114b10ed4eb319e0d2d6fb9b43fb7578c2dbefb13c4d3419099f8ab820a2b8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb00000000000000000000000014f8392a7fedcf8e40cbde99dc3b5629ae6a887c0000000000000000000000000000000000000000000000000de0b6b3a764000026a0da1e5fee3bab46f642b1e0c33b13f9b017ed967917969a6f278dac4f8d01a85da002ea288e9f0dd7138c2c2602b3f1836c0bcc379eb3662e45d0737a809bce1e0bf8ab820a2c8501dcd6500082ca8f946f259637dcd74c767781e37bc6133cd6a68aa16180b844a9059cbb000000000000000000000000fef76c4de9a9d591056cd26ed58478e392c9e1660000000000000000000000000000000000000000000000000de0b6b3a764000025a09609b8ab63a2648b016cb475a3b334b716e1eeb59637fd627348ad92f8e44157a07a27c3484330f4175636e598d1c6c449c786ee0ce56c49bacdfc2946ad85d7c7c0"));
        System.out.println("Size of encoded block: " + Block.MemEstimator.estimateSize(b));
        b.getNumber();
        System.out.println("Size of parsed block: " + Block.MemEstimator.estimateSize(b));
        b.getTransactionsList().forEach(Transaction::getSender);
        System.out.println("Size of parsed block with parsed txes: " + Block.MemEstimator.estimateSize(b));
    }
}